using AutoMapper;
using StudentManagement.Application.DTOs;
using StudentManagement.Domain.Entities;
using StudentManagement.Domain.Repositories;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace StudentManagement.Application.Services
{
    public class RoleService : IRoleService
    {
        private readonly IRoleRepository _roleRepository;
        private readonly IPermissionRepository _permissionRepository;
        private readonly IMapper _mapper;

        public RoleService(IRoleRepository roleRepository, IPermissionRepository permissionRepository, IMapper mapper)
        {
            _roleRepository = roleRepository;
            _permissionRepository = permissionRepository;
            _mapper = mapper;
        }

        public async Task<RoleDTO> GetRoleByIdAsync(int id)
        {
            var role = await _roleRepository.GetByIdAsync(id);
            if (role == null)
            {
                return null;
            }

            var roleDTO = _mapper.Map<RoleDTO>(role);
            return roleDTO;
        }

        public async Task<RoleDTO> GetRoleByNameAsync(string name)
        {
            var role = await _roleRepository.GetRoleByNameAsync(name);
            if (role == null)
            {
                return null;
            }

            var roleDTO = _mapper.Map<RoleDTO>(role);
            return roleDTO;
        }

        public async Task<IEnumerable<RoleDTO>> GetAllRolesAsync()
        {
            var roles = await _roleRepository.GetAllAsync();
            return _mapper.Map<IEnumerable<RoleDTO>>(roles);
        }

        public async Task<IEnumerable<RoleDTO>> GetActiveRolesAsync()
        {
            var roles = await _roleRepository.GetActiveRolesAsync();
            return _mapper.Map<IEnumerable<RoleDTO>>(roles);
        }

        public async Task<RoleDTO> CreateRoleAsync(RoleDTO roleDTO)
        {
            // 检查角色名称是否已存在
            var existingRole = await _roleRepository.GetRoleByNameAsync(roleDTO.Name);
            if (existingRole != null)
            {
                throw new System.Exception("角色名称已存在");
            }

            var role = _mapper.Map<Role>(roleDTO);
            await _roleRepository.AddAsync(role);

            return _mapper.Map<RoleDTO>(role);
        }

        public async Task<RoleDTO> UpdateRoleAsync(int id, RoleDTO roleDTO)
        {
            var role = await _roleRepository.GetByIdAsync(id);
            if (role == null)
            {
                return null;
            }

            // 检查角色名称是否已被其他角色使用
            if (role.Name != roleDTO.Name)
            {
                var existingRole = await _roleRepository.GetRoleByNameAsync(roleDTO.Name);
                if (existingRole != null && existingRole.Id != id)
                {
                    throw new System.Exception("角色名称已存在");
                }
            }

            _mapper.Map(roleDTO, role);
            await _roleRepository.UpdateAsync(role);

            return _mapper.Map<RoleDTO>(role);
        }

        public async Task<bool> DeleteRoleAsync(int id)
        {
            var role = await _roleRepository.GetByIdAsync(id);
            if (role == null)
            {
                return false;
            }

            // 在实际应用中，可能需要检查是否有用户关联到此角色
            // 如果有，可能需要先移除用户的角色关联，或者不允许删除有用户的角色

            await _roleRepository.DeleteAsync(id);
            return true;
        }

        public async Task<IEnumerable<RoleDTO>> SearchRolesAsync(string keyword)
        {
            var roles = await _roleRepository.SearchRolesAsync(keyword);
            return _mapper.Map<IEnumerable<RoleDTO>>(roles);
        }

        public async Task<IEnumerable<PermissionDTO>> GetPermissionsByRoleIdAsync(int roleId)
        {
            var permissions = await _roleRepository.GetPermissionsByRoleIdAsync(roleId);
            return _mapper.Map<IEnumerable<PermissionDTO>>(permissions);
        }

        public async Task<bool> AddPermissionToRoleAsync(int roleId, int permissionId)
        {
            // 检查角色是否存在
            var role = await _roleRepository.GetByIdAsync(roleId);
            if (role == null)
            {
                return false;
            }

            // 检查权限是否存在
            var permission = await _permissionRepository.GetByIdAsync(permissionId);
            if (permission == null)
            {
                return false;
            }

            // 检查权限是否已经添加到角色
            var existingPermissions = await _roleRepository.GetPermissionsByRoleIdAsync(roleId);
            if (existingPermissions.Any(p => p.Id == permissionId))
            {
                return true; // 已经存在，返回成功
            }

            await _roleRepository.AddPermissionToRoleAsync(roleId, permissionId);
            return true;
        }

        public async Task<bool> RemovePermissionFromRoleAsync(int roleId, int permissionId)
        {
            // 检查角色是否存在
            var role = await _roleRepository.GetByIdAsync(roleId);
            if (role == null)
            {
                return false;
            }

            // 检查权限是否存在
            var permission = await _permissionRepository.GetByIdAsync(permissionId);
            if (permission == null)
            {
                return false;
            }

            // 检查权限是否已经添加到角色
            var existingPermissions = await _roleRepository.GetPermissionsByRoleIdAsync(roleId);
            if (!existingPermissions.Any(p => p.Id == permissionId))
            {
                return true; // 不存在，返回成功
            }

            await _roleRepository.RemovePermissionFromRoleAsync(roleId, permissionId);
            return true;
        }
    }
}